package vcp.client.GUI.mvc.model;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;

import vcp.client.forms.SubscriptionForm;
import vcp.client.interfaces.IObservable;
import vcp.client.request.SubmitSubscriptionFormRequest;
import vcp.entity.Customer;
import vcp.entity.Subscription;

/**
 * 
 * @author VCP team
 *         <p>
 *         subscription model
 *         </p>
 */
public class UISubscriptionModel extends UIAbstractModel
{
	/** customer instance **/
	private Customer customer;

	public Customer getCustomer ()
	{
		return this.customer;
	}

	public void setCustomer ( Customer customer )
	{
		this.customer = customer;
	}

	/**
	 * Retrieve the model
	 * 
	 * @param model
	 */
	public UISubscriptionModel ( IObservable model )
	{
		super(model);
	}

	/****************************************************************************************************************************
	 *** Public methods ***
	 ****************************************************************************************************************************/
	/**
	 * 
	 * @return list of numbers fill with subscription id
	 */
	public List <Integer> getCustomerSubscriptionIDs ()
	{
		List <Integer> subscriptionIDs = new ArrayList <>();
		for ( Subscription subscription : this.customer.getSubscriptions() )
		{
			subscriptionIDs.add(subscription.getSubscribtionID());
		}

		return subscriptionIDs;
	}

	/**
	 * insert new subscription id numbers into the list
	 * 
	 * @param subscription
	 */
	public void updateSubscriptionsList ( Subscription subscription )
	{
		Subscription foundSubscription = this.getCustomerSubscriptionIDById(subscription.getSubscribtionID());
		if ( foundSubscription == null )
		{
			this.customer.getSubscriptions().add(subscription);
		}
		else
		{
			foundSubscription.setCars(subscription.getCars());
		}
	}

	/**
	 * 
	 * @param form
	 *            with new subscription info
	 */
	public void applyForm ( SubscriptionForm form )
	{
		SubmitSubscriptionFormRequest request = new SubmitSubscriptionFormRequest(form);
		this.sendRequest(request, true);
	}

	/****************************************************************************************************************************
	 *** Private methods ***
	 ****************************************************************************************************************************/
	/**
	 * 
	 * @param subscribtionID
	 * @return subscription by id
	 */
	private Subscription getCustomerSubscriptionIDById ( int subscribtionID )
	{
		Subscription foundSubscription = null;
		for ( Subscription subscription : this.getCustomer().getSubscriptions() )
		{
			if ( subscription.getSubscribtionID() == subscribtionID )
			{
				foundSubscription = subscription;
				break;
			}
		}

		return foundSubscription;
	}

	/**
	 * update customer balance
	 * 
	 * @param updatedBalance
	 */
	private void updateCustomerBalance ( Float updatedBalance )
	{
		this.customer.setBalance(updatedBalance.floatValue());
	}

	/****************************************************************************************************************************
	 *** UIAbstractModel methods ***
	 ****************************************************************************************************************************/
	@Override
	public void clearModel ()
	{
		this.customer = null;
	}

	/****************************************************************************************************************************
	 *** Observer methods ***
	 ****************************************************************************************************************************/
	@SuppressWarnings ( "unchecked" )
	@Override
	public void update ( Object data )
	{
		if ( data instanceof List <?> )
		{
			List <Serializable> serializableInfo = (List <Serializable>) data;

			if ( serializableInfo.size() > 1 )
			{
				Subscription subscription = (Subscription) serializableInfo.get(0);
				this.updateSubscriptionsList(subscription);

				String userInfo = (String) serializableInfo.get(1);
				this.controllerDelegate.updateControllerDelegateWithData(userInfo);

				Float updatedBalance = (Float) serializableInfo.get(2);
				this.updateCustomerBalance(updatedBalance);

				this.controllerDelegate.updateControllerDelegateWithData(null);
			}
			else
			{
				String userInfo = (String) serializableInfo.get(0);
				this.controllerDelegate.updateControllerDelegateWithData(userInfo);
			}

			this.controllerDelegate.loadingStop();
		}
	}

}
